<template>
  <div class="carousel-logo" @mouseenter="isHover = true" @mouseleave="isHover = false">
    <div class="carousel-logo__container" :class="[modelValue?.width ? `container-content-${modelValue?.width}` : 'container-content']">
      <template v-if="!modelValue?.isNoSlide">
        <client-only>
          <swiper
            ref="mySwiperRef"
            :modules="modules"
            :slides-per-view="1"
            :centeredSlides="true"
            :speed="600"
            :autoplay="swiperOptions.autoplay"
            class="swiper carousel-logo__swiper"
            @slideChange="onSwiperSlideChange"
            @swiper="onSwiperReady"
          >
            <swiper-slide
              v-for="(page, idx) in list"
              class="swiper-slide"
              :key="idx"
            >
              <div
                class="slide-content row"
                :class="`row-cols-${perChunk}`"
                v-for="(row, rowIdx) in page"
                :key="`logo-${rowIdx}`"
              >
                <div
                  class="logo-card col flex-center flex-column"
                  v-for="(col, colIdx) in row"
                  :key="`logo-${colIdx}`"
                >
                  <a
                    v-if="col.link"
                    :href="col.link"
                    target="_blank"
                    class="logo-card__img"
                    :class="{ 'logo-card__img--no-clip': modelValue?.isNoClip }"
                  >
                    <img :src="col.imgSrc" :alt="col.alt || col.name" />
                  </a>

                  <div
                    v-else-if="modelValue?.isPureLogo"
                    class="logo-card__img logo-card__img--is-pure-logo"
                    :class="{ 'logo-card__img--no-clip': modelValue?.isNoClip }"
                  >
                    <img :src="col.imgSrc" :alt="col.alt || col.name" />
                  </div>

                  <div
                    v-else
                    class="logo-card__img"
                    :class="{ 'logo-card__img--no-clip': modelValue?.isNoClip }"
                    @click="openLightbox(col)"
                  >
                    <img :src="col.imgSrc" :alt="col.alt || col.name" />
                  </div>

                  <div class="logo-card__name tx-overline text-center" :class="{ 'mt-2': !col.link }">
                    {{ col.name }}
                  </div>
                </div>
              </div>
            </swiper-slide>
          </swiper>

          <div class="mt-6 mt-md-10" v-if="list.length > 1">
            <SlidesPagination
              :currentIndex="currentIndex"
              :count="list.length"
              @updatePage="updatePage"
              dark
            />
          </div>
        </client-only>
      </template>

      <div v-else class="carousel-logo__row row row-cols-3 row-cols-sm-4 row-cols-md-6">
        <div class="logo-card col flex-center flex-column" v-for="(col, colIdx) in modelValue?.data" :key="`logo-${colIdx}`">
          <a
            v-if="col.link"
            :href="col.link"
            target="_blank"
            class="logo-card__img"
            :class="{ 'logo-card__img--no-clip': modelValue?.isNoClip }"
          >
            <img :src="col.imgSrc" :alt="col.alt || col.name" />
          </a>

          <div
            v-else-if="modelValue?.isPureLogo"
            class="logo-card__img logo-card__img--is-pure-logo"
            :class="{ 'logo-card__img--no-clip': modelValue?.isNoClip }"
          >
            <img :src="col.imgSrc" :alt="col.alt || col.name" />
          </div>

          <div
            v-else
            class="logo-card__img"
            :class="{ 'logo-card__img--no-clip': modelValue?.isNoClip }"
            @click="openLightbox(col)"
          >
            <img :src="col.imgSrc" :alt="col.alt || col.name" />
          </div>

          <div class="logo-card__name tx-overline text-center" :class="{ 'mt-2': !col.link }">
            {{ col.name }}
          </div>
        </div>
      </div>
    </div>

    <Operate v-if="!isPreview" v-model:show="isHover" @handle-edit="showSetting = true" @handle-delete="handleDelete" @handle-copy="handleCopy" @handle-paste="handlePaste"></Operate>
  </div>

  <Setting v-if="!isPreview" v-model:show="showSetting" :data="modelValue"></Setting>
</template>

<script lang="ts" setup>
import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue';
import SlidesPagination from '@/common/SlidesPagination/index.vue';
import { Swiper, SwiperSlide } from 'swiper/vue';
import { Navigation, Pagination, Autoplay } from "swiper/modules";
import { randomString } from '@/utils/common'
import Setting from './setting.vue'
import Operate from '@/common/Operate/index.vue'
import 'swiper/css';
import 'swiper/css/autoplay';
import 'swiper/css/navigation';
import 'swiper/css/pagination';

// 定义组件名称
defineOptions({
  name: 'CarouselLogo'
})

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => {}
  },

  // 是否预览
  isPreview: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['update:modelValue', 'handleDelete', 'handleCopy', 'handlePaste', 'handleClick'])

const handleInit = () => {
  if (props.modelValue && props.modelValue?.data) return // 有数据不用初始化
  const data = {
    id: props.modelValue?.id || randomString(),
    type: 'CarouselLogo',
    width: '',
    isNoClip: undefined,
    isPureLogo: undefined,
    isNoSlide: undefined,
    data: [
      {
        id: randomString(),
        name: '耀华国际',
        imgSrc: 'https://osswebsite.ycyw.com/media-library/ywies-bj/images/home/ywies-tx.jpg',
        alt: '',
        link: 'https://www.baidu.com'
      },
    ]
  }
  emit('update:modelValue', data)
} 

const isHover = ref<boolean>(false);
const showSetting = ref<boolean>(false);

const handleDelete = () => {
  emit('handleDelete', props.modelValue?.id)
}

const handleCopy = () => {
  emit('handleCopy', props.modelValue)
}

const handlePaste = (type: string) => {
  emit('handlePaste', type)
}

const modules = [Navigation, Pagination, Autoplay]; // keep empty or add as needed (Navigation, Pagination, Autoplay...)
const swiperOptions = {
  autoplay: {
    delay: 5000
  }
};

const vsWidth = ref(typeof window !== 'undefined' ? window.innerWidth : 1024);
function handleResize() {
  vsWidth.value = typeof window !== 'undefined' ? window.innerWidth : 1024;
}
onMounted(() => {
  if (typeof window !== 'undefined') if (typeof window !== 'undefined') window.addEventListener('resize', handleResize);
});
onBeforeUnmount(() => {
  if (typeof window !== 'undefined') if (typeof window !== 'undefined') window.removeEventListener('resize', handleResize);
});

const perChunk = computed(() => {
  const w = vsWidth.value;
  if (w >= 1280) return 6;
  if (w >= 992) return 5;
  if (w >= 768) return 4;
  return 3
});

const perRowChunk = computed(() => {
  return vsWidth.value >= 768 ? 2 : 3;
});

const list = computed(() => {
  const src = props.modelValue?.data || [];
  const chunkedByCol: any[] = src.reduce((resultArray: any[], item: any, index: number) => {
    const chunkIndex = Math.floor(index / perChunk.value);
    if (!resultArray[chunkIndex]) resultArray[chunkIndex] = [];
    resultArray[chunkIndex].push(item);
    return resultArray;
  }, []);

  const rowed = chunkedByCol.reduce((resultArray: any[], item: any, index: number) => {
    const chunkIndex = Math.floor(index / perRowChunk.value);
    if (!resultArray[chunkIndex]) resultArray[chunkIndex] = [];
    resultArray[chunkIndex].push(item);
    return resultArray;
  }, []);

  return rowed;
});

const currentIndex = ref(0)
const swiperInstance = ref<any>()
const isRerender = ref(false)
const onSwiperReady = (swiper: any) => {
  swiperInstance.value = swiper
  if (!isRerender.value) {
    nextTick(() => {
      setTimeout(() => {
        reRender()
      }, 100);
    })
  }
}
const reRender = (() => {
  nextTick(() => {
    if (swiperInstance.value) {
      swiperInstance.value.update();
      isRerender.value = true;
    }
  });
})
// Swiper 事件处理 - 新版本写法
const onSwiperSlideChange = (swiper: any) => {
  currentIndex.value = swiper.realIndex ?? 0;
}

// 分页控制函数 - 新版本写法
const updatePage = ((idx: number) => {
  if (swiperInstance.value) {
    swiperInstance.value.slideToLoop(idx, 600);
  }
})

function openLightbox(obj: any) {
  if (!obj.link) return;
  if (obj.link.startsWith('http')) {
    if (typeof window !== 'undefined') window.open(obj.link, '_blank');
  } else {
    emit('handleClick', obj.link);
  }
}

onMounted(() => {
  reRender()
})

handleInit()
</script>

<style lang="scss" scoped>
.row {
  --bs-gutter-x: 16px;
  --bs-gutter-y: 0;
  display: flex;
  flex-wrap: wrap;
  margin-top: calc(var(--bs-gutter-y)*-1);
  margin-right: calc(var(--bs-gutter-x)*-0.5);
  margin-left: calc(var(--bs-gutter-x)*-0.5)
}

.row>* {
  flex-shrink: 0;
  width: 100%;
  max-width: 100%;
  padding-right: calc(var(--bs-gutter-x)*0.5);
  padding-left: calc(var(--bs-gutter-x)*0.5);
  margin-top: var(--bs-gutter-y)
}

.col {
  flex: 1 0 0%
}

.row-cols-auto>* {
  flex: 0 0 auto;
  width: auto
}

.row-cols-1>* {
  flex: 0 0 auto;
  width: 100%
}

.row-cols-2>* {
  flex: 0 0 auto;
  width: 50%
}

.row-cols-3>* {
  flex: 0 0 auto;
  width: 33.3333333333%
}

.row-cols-4>* {
  flex: 0 0 auto;
  width: 25%
}

.row-cols-5>* {
  flex: 0 0 auto;
  width: 20%
}

.row-cols-6>* {
  flex: 0 0 auto;
  width: 16.6666666667%
}

.flex-center {
  display: flex;
  align-items: center;
  justify-content: center
}
.flex-column {
  flex-direction: column!important
}

.tx-overline {
  font-size: 14px;
  font-weight: 400;
  line-height: 1.285;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
@media (max-width: 1023.98px) {
  .tx-overline {
    font-size: 13px;
    line-height: 1;
  }
}

@media (max-width: 767.98px) {
  .tx-overline {
    line-height: 1.66;
  }
}
.text-center {
  text-align: center!important
}
.mt-2 {
  margin-top: 8px!important
}
.mt-6 {
  margin-top: 24px!important
}
.mt-md-10 {
  @media (min-width: 768px) {
    margin-top: 40px!important
  }
}

.row-cols-sm-4>* {
  @media (min-width: 576px) {
    flex: 0 0 auto;
    width: 25%
  }
}
.row-cols-md-6>* {
  @media (min-width: 768px) {
    flex: 0 0 auto;
    width: 16.6666666667%
  }
}

.carousel-logo {
  padding-top: 80px;
  padding-bottom: 65px;
}

@media (max-width: 767.98px) {
  .carousel-logo {
    padding-top: 60px;
    padding-bottom: 40px;
  }
}

.carousel-logo__swiper .slide-content {
  align-items: baseline;
}

.carousel-logo__swiper .slide-content:not(:first-child) {
  margin-top: 50px;
}

@media (max-width: 767.98px) {
  .carousel-logo__swiper .slide-content:not(:first-child) {
    margin-top: 20px;
  }
}

.carousel-logo__swiper .slide-content .logo-card__img {
  width: 80px;
  height: 80px;
  cursor: pointer;
  border-radius: 50%;
  overflow: hidden;
}

@media (max-width: 767.98px) {
  .carousel-logo__swiper .slide-content .logo-card__img {
    width: 60px;
    height: 60px;
  }
}

.carousel-logo__swiper .slide-content .logo-card__img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.carousel-logo__swiper .slide-content .logo-card__img--no-clip {
  border-radius: 0;
  overflow: visible;
}

.carousel-logo__swiper .slide-content .logo-card__img--no-clip img {
  object-fit: contain;
}

.carousel-logo__swiper .slide-content .logo-card__img--is-pure-logo {
  cursor: initial;
}

.carousel-logo__swiper .slide-content .logo-card__name {
  @extend .tx-overline;
  color: #1A1C20;
  max-width: 160px;
  margin-top: 8px;
}

@media (max-width: 767.98px) {
  .carousel-logo__swiper .slide-content .logo-card__name {
    max-width: 100px;
    font-size: 10px;
    line-height: 1.2;
    letter-spacing: 0.04em;
    margin-top: 6px;
  }
}

.carousel-logo__swiper .slide-content .logo-card__desc {
  color: #64788F;
}

@media (max-width: 767.98px) {
  .carousel-logo__swiper .slide-content .logo-card__desc {
    max-width: 90px;
  }
}

/* row (no-slide) layout */
.carousel-logo__row {
  --bs-gutter-x: 16px;
  --bs-gutter-y: 50px;
}
@media (max-width: 767.98px) {
  .carousel-logo__row {
    --bs-gutter-y: 32px;
  }
}
@media (max-width: 575.98px) {
  .carousel-logo__row {
    --bs-gutter-y: 20px;
  }
}

.carousel-logo__row .logo-card__img {
  width: 80px;
  height: 80px;
  cursor: pointer;
  border-radius: 50%;
  overflow: hidden;
}
@media (max-width: 767.98px) {
  .carousel-logo__row .logo-card__img  {
    width: 60px;
    height: 60px;
  }
}
@media (max-width: 1023.98px) {
  .carousel-logo__row .logo-card__img  {
    width: 65px;
    height: 65px;
  }
}

.carousel-logo__row .logo-card__img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.carousel-logo__row .logo-card__img--no-clip {
  border-radius: 0;
  overflow: visible;
}

.carousel-logo__row .logo-card__img--no-clip img {
  object-fit: contain;
}

.carousel-logo__row .logo-card__img--is-pure-logo {
  cursor: initial;
}

.carousel-logo__row .logo-card__name {
  @extend .tx-overline;
  color: #1A1C20;
  max-width: 160px;
  margin-top: 8px;
}
@media (max-width: 767.98px) {
  .carousel-logo__row .logo-card__name {
    max-width: 100px;
    font-size: 10px;
    line-height: 1.2;
    letter-spacing: 0.04em;
    margin-top: 6px;
  }
}
@media (max-width: 1023.98px) {
  .carousel-logo__row .logo-card__name {
    font-size: 12px;
  }
}

.carousel-logo__row .logo-card__desc {
  color: #64788F;
}
@media (max-width: 767.98px) {
  .carousel-logo__row .logo-card__desc {
    max-width: 90px;
  }
}
</style>